/***********************************************************************
*  ipinnet - Check if IP is in network.
*  Copyright (C) 2020  CYBERDEViL
*
*  This file is part of ipinnet.
*
*  Searx-qt is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  ipinnet is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program.  If not, see <https://www.gnu.org/licenses/>.
*
***********************************************************************/

// https://docs.python.org/3/extending/extending.html
// https://realpython.com/build-python-c-extension-module/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "ipinnet.h"

/* Module methods */
static PyObject *method_ipv4_in_net(PyObject *self, PyObject *args) {
    char *addr, *net = NULL;
    uint8_t bits = 0, *bits_ptr;
    bits_ptr = &bits;

    if(!PyArg_ParseTuple(args, "ssB", &addr, &net, bits_ptr)) {
        return NULL;
    }
    return PyLong_FromUnsignedLong(addr_in_network(addr, net, bits));
}

static PyObject *method_ipv6_in_net(PyObject *self, PyObject *args) {
    char *addr, *net = NULL;
    uint8_t bits = 0, *bits_ptr;
    bits_ptr = &bits;

    if(!PyArg_ParseTuple(args, "ssb", &addr, &net, bits_ptr)) {
        return NULL;
    }
    return PyLong_FromUnsignedLong(ipv6_addr_in_network(addr, net, bits));
}

/* Module defenitions */
static PyMethodDef IpInNetMethods[] = {
    {"ipv4_in_net", method_ipv4_in_net, METH_VARARGS, "Check if given IPv4 address is in given IPV4 network."},
    {"ipv6_in_net", method_ipv6_in_net, METH_VARARGS, "Check if given IPv6 address is in given IPV6 network."},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef ipinnetmodule = {
    PyModuleDef_HEAD_INIT,
    "ipinnet",
    "IP in net.",
    -1,
    IpInNetMethods
};


/* Module init */
PyMODINIT_FUNC PyInit_ipinnet(void) {
    PyObject *module = PyModule_Create(&ipinnetmodule);

    // Some constants
    PyModule_AddIntConstant(module, "MATCH", 0);
    PyModule_AddIntConstant(module, "NO_MATCH", 1);
    PyModule_AddIntConstant(module, "INVALID_IP", 2);
    PyModule_AddIntConstant(module, "INVALID_NET", 3);

    return module;
}

